"""Copyright 2011 Thomas Anesta, Jonathan Brenner, Tyler Moylat, Rosa Tung, Sean Kim"""

"""

This file is part of Bubbles

Bubbles is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Bubbles is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

"""
import sys, pygame
import BubblesConstants

BUBBLE_S_WIDTH = 42
BUBBLE_S_HEIGHT = 42
BUBBLE_S_XVEL = 9
BUBBLE_S_YVEL = 11
BUBBLE_M_WIDTH = 64
BUBBLE_M_HEIGHT = 64
BUBBLE_M_XVEL = 8
BUBBLE_M_YVEL = 10
BUBBLE_L_WIDTH = 86
BUBBLE_L_HEIGHT = 86
BUBBLE_L_XVEL = 6
BUBBLE_L_YVEL = 8

BUBBLE_MAX_SIZE = 1
BUBBLE_MIN_SIZE = -1
BUBBLE_MIN_NORMAL_SIZE = 0
BUBBLE_MAX_NORMAL_SIZE = 0
BUBBLE_DEFAULT_SIZE = 0

BUBBLE_S_VAL = 0
BUBBLE_M_VAL = 1
BUBBLE_L_VAL = 2

BUBBLE_HEALTH = 15

BUBBLE_FRAMES = 4
BUBBLE_FRAME_DELAY = 3
BUBBLE_HIT_DELAY = 16
BUBBLE_DEATH_FRAMES = BUBBLE_FRAME_DELAY * BUBBLE_FRAMES#total frames until dying

BUBBLE_INITIAL_X = BubblesConstants.WINDOW_WIDTH/2 - BUBBLE_M_WIDTH/2
BUBBLE_INITIAL_Y = (BubblesConstants.WINDOW_HEIGHT - BubblesConstants.WINDOW_HUD)*3/4

class Player(object):
    def __init__(self):
        """creates the bubble"""
        self.type = BubblesConstants.PLAYER_TYPE
        self.image_s = pygame.image.load("gfx/S_Bubble.png").convert_alpha()
        self.image_m = pygame.image.load("gfx/M_Bubble.png").convert_alpha()
        self.image_l = pygame.image.load("gfx/L_Bubble.png").convert_alpha()
        self.death_image_s = pygame.image.load("gfx/S_Bubble_Death.png").convert_alpha()
        self.death_image_m = pygame.image.load("gfx/M_Bubble_Death.png").convert_alpha()
        self.death_image_l = pygame.image.load("gfx/L_Bubble_Death.png").convert_alpha()
        
        self.image = self.image_m # default
        self.rect = self.image_m.get_rect()
        self.rect.width = BUBBLE_M_WIDTH
        self.rect.height = BUBBLE_M_HEIGHT
        self.rect.x = BUBBLE_INITIAL_X
        self.rect.y = BUBBLE_INITIAL_Y
        self.xpos = self.rect.x + self.rect.width/2
        self.ypos = self.rect.y + self.rect.height/2
        self.radius = self.rect.width/2
        self.xvel = BUBBLE_M_XVEL
        self.yvel = BUBBLE_M_YVEL
        self.moving = [False, False, False, False] #up, down, left, right
        #self.alive = True
        
        self.size = 0#BUBBLE_DEFAULT_SIZE
        self.size_code = BUBBLE_M_VAL
        #self.size_val = BUBBLE_M_VAL # -1 is small, 0 is normal, 1 is large
        
        self.status = BubblesConstants.STATUS_ACTIVE
        self.health = BUBBLE_HEALTH
        self.h_sound = pygame.mixer.Sound("sfx/bubble_hit.wav")
        
        self.frames = 0
        self.frames_num = BUBBLE_FRAMES
        self.f_delay = BUBBLE_FRAME_DELAY
        self.hit_dif = BUBBLE_HIT_DELAY
        self.is_hit = False
        self.hit_frame = int(0)
        self.death_frames = BUBBLE_DEATH_FRAMES
        
    def update(self):
        """updates position of the bubble"""
         
        if self.moving[0] and self.moving[1]:
            pass
        elif self.moving[2] and self.moving[3]:
            pass
        
        if self.moving[0]:
            future = self.rect.move(0, -self.yvel)
            if future.top < 0:
                self.rect.top = 0
            else:
                self.rect = future
        elif self.moving[1]:
            future = self.rect.move(0, self.yvel)
            if future.bottom > BubblesConstants.WINDOW_HEIGHT - BubblesConstants.WINDOW_HUD:
                self.rect.bottom = BubblesConstants.WINDOW_HEIGHT - BubblesConstants.WINDOW_HUD
            else:
                self.rect = future
        if self.moving[2]:
            self.direction = 1
            future = self.rect.move(-self.xvel, 0)
            if future.left < 0:
                self.rect.left = 0
            else:
                self.rect = future
        elif self.moving[3]:
            self.direction = 0
            future = self.rect.move(self.xvel, 0)
            if future.right > BubblesConstants.WINDOW_WIDTH:
                self.rect.right = BubblesConstants.WINDOW_WIDTH
            else:
                self.rect = future
                
        self.xpos = self.rect.x + self.rect.width/2
        self.ypos = self.rect.y + self.rect.height/2
        self.radius = self.rect.width/2
        
    def powerup(self, offset):
        if self.status == BubblesConstants.STATUS_DEAD:
            return
        futureval = self.size + offset
        if futureval > BUBBLE_MAX_SIZE:
            self.size = BUBBLE_MAX_SIZE
        elif futureval < BUBBLE_MIN_SIZE:
            self.size = BUBBLE_MIN_SIZE
        else:
            self.size += offset
            
        self.update_size()
            
    def update_size(self):
        """update size of player"""
        if self.size < BUBBLE_MIN_NORMAL_SIZE:
            self.image = self.image_s
            self.rect.width = BUBBLE_S_WIDTH
            self.rect.height = BUBBLE_S_HEIGHT
            self.xvel = BUBBLE_S_XVEL
            self.yvel = BUBBLE_S_YVEL
            self.size_code = BUBBLE_S_VAL
        elif self.size > BUBBLE_MAX_NORMAL_SIZE:
            self.image = self.image_l
            self.rect.width = BUBBLE_L_WIDTH
            self.rect.height = BUBBLE_L_HEIGHT
            self.xvel = BUBBLE_L_XVEL
            self.yvel = BUBBLE_L_YVEL
            self.size_code = BUBBLE_L_VAL
        else:#if equal to or between the sizes for mid
            self.image = self.image_m
            self.rect.width = BUBBLE_M_WIDTH
            self.rect.height = BUBBLE_M_HEIGHT
            self.xvel = BUBBLE_M_XVEL
            self.yvel = BUBBLE_M_YVEL
            self.size_code = BUBBLE_M_VAL
            
    def take_damage(self, damage):
        if self.is_hit == False:
            self.health -= damage
            self.is_hit = True
            self.hit_frame = self.frames
            if self.health <= 0:
                self.status = BubblesConstants.STATUS_DEAD

                #assign image
                if self.size_code == BUBBLE_S_VAL:

                    self.image = self.death_image_s
                    self.rect = self.image.get_rect()
                    self.rect.width = BUBBLE_S_WIDTH
                    self.rect.height = BUBBLE_S_HEIGHT
                    self.rect.centerx = self.xpos
                    self.rect.centery = self.ypos
                elif self.size_code == BUBBLE_M_VAL:

                    self.image = self.death_image_m
                    self.rect = self.image.get_rect()
                    self.rect.width = BUBBLE_M_WIDTH
                    self.rect.height = BUBBLE_M_HEIGHT
                    self.rect.centerx = self.xpos
                    self.rect.centery = self.ypos
                else:#is large

                    self.image = self.death_image_l
                    self.rect = self.image.get_rect()
                    self.rect.width = BUBBLE_L_WIDTH
                    self.rect.height = BUBBLE_L_HEIGHT
                    self.rect.centerx = self.xpos
                    self.rect.centery = self.ypos
        
        self.h_sound.play()
        return self.health
    
    def draw(self, screen):
        """draws the bubble"""
        if self.status == BubblesConstants.STATUS_DEAD:
            return
        elif self.is_hit == True:
            if (self.frames - self.hit_frame) < self.hit_dif:
                screen.blit(self.image, self.rect, pygame.Rect(self.rect.width * ((self.frames/self.f_delay) % self.frames_num), (self.frames % 2)*self.rect.height, self.rect.width, self.rect.height))
                self.advance_frame()
                return
            else:
                self.is_hit = False
        else: 
            pass
        
        screen.blit(self.image, self.rect, pygame.Rect(self.rect.width * ((self.frames/self.f_delay) % self.frames_num), 0, self.rect.height, self.rect.height))
        self.advance_frame()
        
    def draw_death(self, screen):
        
        screen.blit(self.image, self.rect, pygame.Rect(self.rect.width * ( (self.frames - self.hit_frame)/self.f_delay), 0, self.rect.width, self.rect.height))
        self.advance_frame()
        
    def advance_frame(self):
        self.frames += 1

